export class datetimeUtil {
    /**
     * 格式化时间戳或Date对象为指定格式的字符串
     * @param time 时间戳(毫秒)或Date对象
     * @param format 格式字符串，如 "yyyy-MM-dd HH:mm:ss"
     * @returns 格式化后的时间字符串
     * @example
     * TimeStringUtils.format(Date.now(), "yyyy-MM-dd") => "2023-05-15"
     * TimeStringUtils.format(new Date(), "HH:mm:ss") => "14:30:45"
     */
    static format(time: number | Date, format: string = "yyyy-MM-dd HH:mm:ss"): string {
        const date = time instanceof Date ? time : new Date(time);
        
        const padZero = (num: number): string => num.toString().padStart(2, '0');
        
        const replacements: Record<string, string | number> = {
            'yyyy': date.getFullYear().toString(),
            'MM': padZero(date.getMonth() + 1),
            'dd': padZero(date.getDate()),
            'HH': padZero(date.getHours()),
            'mm': padZero(date.getMinutes()),
            'ss': padZero(date.getSeconds()),
            'SSS': padZero(date.getMilliseconds()).padStart(3, '0'),
            "M": date.getMonth() + 1,
            'd': date.getDate(),
            'H': date.getHours(),
            'm': date.getMinutes(),
            's': date.getSeconds(),
            'S': date.getMilliseconds(),
            'A': date.getHours() >= 12 ? 'PM' : 'AM',
            'a': date.getHours() >= 12 ? 'pm' : 'am',
            'ZZ': `${padZero(Math.abs(date.getTimezoneOffset() / 60))}${padZero(date.getTimezoneOffset() % 60)}`,
        };
        
        return format.replace(/(yyyy|yy|MM|M|dd|d|HH|H|mm|m|ss|s|SSS|S|A|a|ZZ)/g, (match:any) => {
            return replacements[match] || match;
        });
    }

    /**
     * 将时间字符串转换为Date对象
     * @param timeStr 时间字符串
     * @param format 格式字符串（用于解析）
     * @returns Date对象，解析失败返回
     * @example
     * TimeStringUtils.parse("2023-05-15", "yyyy-MM-dd") => Date对象
     */
    static parse(timeStr: string, format: string = "yyyy-MM-dd HH:mm:ss"): Date  {
        // 简单的解析实现，对于复杂需求建议使用moment.js或date-fns`
        const now = new Date();
        const year = now.getFullYear();
        const month = now.getMonth();
        const day = now.getDate();
        const hours = now.getHours();
        const minutes = now.getMinutes();
        const seconds = now.getSeconds();
        
        // 提取格式中的各个部分
        const parts = format.match(/(yyyy|yy|MM|M|dd|d|HH|H|mm|m|ss|s|SSS|S)/g) || [];
        const values = timeStr.match(/\d+/g) || [];
        
        if (parts.length !== values.length)  throw new Error("格式不匹配");
        
        let y = year, M = month, d = day, H = hours, m = minutes, s = seconds, S = 0;
        
        parts.forEach((part, i) => {
            const value = parseInt(values[i], 10);
            switch (part) {
                case 'yyyy': y = value; break;
                case 'yy': y = 2000 + value; break;
                case 'MM': M = value - 1; break;
                case 'M': M = value - 1; break;
                case 'dd': d = value; break;
                case 'd': d = value; break;
                case 'HH': H = value; break;
                case 'H': H = value; break;
                case 'mm': m = value; break;
                case 'm': m = value; break;
                case 'ss': s = value; break;
                case 's': s = value; break;
                case 'SSS': S = value; break;
                case 'S': S = value; break;
            }
        });
        
        const date = new Date(y, M, d, H, m, s, S);
        // 验证日期是否有效
        if (isNaN(date.getTime())) throw new Error("无效的日期");
        return date;
    }

    /**
     * 计算时间差并格式化为易读字符串
     * @param startTime 开始时间(时间戳或Date)
     * @param endTime 结束时间(时间戳或Date)，默认为当前时间
     * @returns 格式化后的时间差字符串
     * @example
     * TimeStringUtils.timeAgo(Date.now() - 3600000) => "1小时前"
     */
    static timeAgo(startTime: number | Date, endTime: number | Date = Date.now()): string {
        const start = startTime instanceof Date ? startTime.getTime() : startTime;
        const end = endTime instanceof Date ? endTime.getTime() : endTime;
        const diff = Math.abs(end - start);
        
        const seconds = Math.floor(diff / 1000);
        const minutes = Math.floor(seconds / 60);
        const hours = Math.floor(minutes / 60);
        const days = Math.floor(hours / 24);
        const months = Math.floor(days / 30);
        const years = Math.floor(days / 365);
        
        if (seconds < 60) {
            return `${seconds}秒${end > start ? '后' : '前'}`;
        } else if (minutes < 60) {
            return `${minutes}分钟${end > start ? '后' : '前'}`;
        } else if (hours < 24) {
            return `${hours}小时${end > start ? '后' : '前'}`;
        } else if (days < 30) {
            return `${days}天${end > start ? '后' : '前'}`;
        } else if (months < 12) {
            return `${months}个月${end > start ? '后' : '前'}`;
        } else {
            return `${years}年${end > start ? '后' : '前'}`;
        }
    }

    /**
     * 将秒数格式化为 "HH:MM:SS" 格式
     * @param seconds 秒数
     * @returns 格式化后的时间字符串
     * @example
     * TimeStringUtils.secondsToHHMMSS(3665) => "01:01:05"
     */
    static secondsToHHMMSS(seconds: number): string {
        const h = Math.floor(seconds / 3600);
        const m = Math.floor((seconds % 3600) / 60);
        const s = Math.floor(seconds % 60);
        
        return [
            h.toString().padStart(2, '0'),
            m.toString().padStart(2, '0'),
            s.toString().padStart(2, '0')
        ].join(':');
    }

    /**
     * 将毫秒格式化为易读字符串
     * @param ms 毫秒数
     * @returns 格式化后的时间字符串
     * @example
     * TimeStringUtils.msToReadable(3605000) => "1小时0分5秒"
     */
    static msToReadable(ms: number): string {
        const seconds = Math.floor(ms / 1000);
        const minutes = Math.floor(seconds / 60);
        const hours = Math.floor(minutes / 60);
        const days = Math.floor(hours / 24);
        
        const s = seconds % 60;
        const m = minutes % 60;
        const h = hours % 24;
        const d = days;
        
        const parts: string[] = [];
        if (d > 0) parts.push(`${d}天`);
        if (h > 0) parts.push(`${h}小时`);
        if (m > 0) parts.push(`${m}分`);
        if (s > 0 || parts.length === 0) parts.push(`${s}秒`);
        
        return parts.join('');
    }

    /**
     * 获取当前时间的ISO字符串（去除末尾的Z）
     * @param includeMilliseconds 是否包含毫秒
     * @returns ISO格式时间字符串
     */
    static getISOString(includeMilliseconds: boolean = false): string {
        const date = new Date();
        const iso = date.toISOString();
        return includeMilliseconds ? iso : iso.replace(/(\.\d+)?Z$/, '');
    }

    /**
     * 获取当前时间戳（秒或毫秒）
     * @param inMilliseconds 是否返回毫秒时间戳，默认为true
     * @returns 时间戳
     */
    static getTimestamp(inMilliseconds: boolean = true): number {
        return inMilliseconds ? Date.now() : Math.floor(Date.now() / 1000);
    }
}

// 使用示例
// console.log(TimeStringUtils.format(Date.now(), "yyyy-MM-dd HH:mm:ss"));
// console.log(TimeStringUtils.format(new Date(), "yyyy年MM月dd日 HH时mm分ss秒"));
// console.log(TimeStringUtils.parse("2023-05-15", "yyyy-MM-dd"));
// console.log(TimeStringUtils.timeAgo(Date.now() - 3600000));
// console.log(TimeStringUtils.secondsToHHMMSS(3665));
// console.log(TimeStringUtils.msToReadable(3605000));
// console.log(TimeStringUtils.getISOString());
// console.log(TimeStringUtils.getTimestamp(false));